#include "serveur.h"
#include "liste.h"
#include <signal.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

volatile sig_atomic_t STOP = 0;

#include "elemGenerique.h"
#include "gestionFile.h"
#include "gestionFichier.h"
#include "gestionThread.h"

int main (int argc, char* argv[])
{
  if(argc == 3 || argc == 4)
    {
      /* Déclarations */
      void *res;
      int retval;
      char ret = 'A';
      int socket;
      int sClient;
      int i;
      /* Declaration des arguments */
      const char* port;
      int nbThread = 0;
      char * pathFile;
      /* Declaration du tableau de thread */
      pthread_t *tabThread;	
      /* Declaration des FD_SET */
      fd_set rfds, rfds_tot;
      /* Declaration du message pour sokspair */
      char msg;
      /* Declaration du tableau de thread */
      gThread gThread;
      /* Initialisation des arguments */
      port = argv[1];
      nbThread = atoi(argv[2]);
      pathFile = "./Films/";
      if(argc == 4)
	pathFile = argv[3];      
      /* Declaration de gThread */
      initialiseGThread(&gThread, (10+nbThread), pathFile);
      /* Initialisation du tableau de treads */
      tabThread = (pthread_t *) malloc (nbThread * sizeof(pthread_t));
      /* Initialisation des threads */
      for (i = 0; i< nbThread; i++)
	{
	  pthread_create(&tabThread[i], NULL,(void * (*)(void *)) threadAttenteSocket, &gThread);
	}
      /* Création de la socket d'écoute */
      socket = creationSocket_Serveur(port);
      /* Initialisation des FD_SET */
      FD_ZERO(&rfds_tot);
      FD_SET(socket, &rfds_tot);
      FD_SET(STDIN_FILENO, &rfds_tot);
      
      do
	{
	  FD_ZERO(&rfds);
	  rfds = rfds_tot;
	  retval = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
	  if(retval == -1) {
	    if(errno != EINTR)
	      {
		perror("\n[svr]! Erreur main : select.\n");
		exit(1);
	      }
	    else 
	      break;
	  }
	  if(FD_ISSET(socket, &rfds))
	    {
	      sClient = attenteConnexion_Serveur(socket);
	      if(send(sClient, "HELO\n", 5, 0) == -1)
		fprintf(stdout, "\n[svr]! Erreur main : send HELO.\n");
	      if(InsererFile(sClient, &gThread.gFile) == 1)
		fprintf(stdout, "\n[svr]! Erreur main : InsererFile.\n");
	    }
	  if(FD_ISSET(STDIN_FILENO, &rfds))
	    {
	      ret = getc(stdin);
	      while(getc(stdin) != '\n');
	    }
	}while(ret != 'Q');
      printf("\n[svr]> Fermeture des differents clients.\n");
      STOP = 1;
      /* Envoi d'une commande d'interruption des threads */
      msg = 'Q';
      for(i=0; i < nbThread; i++)
	{
	  write(gThread.gFile.sockPair[1], &msg, sizeof(char));
	}
      /* Fermeture et liberation des threads */
      pthread_cond_broadcast(&gThread.gFile.non_vide);
      for(i=0; i < nbThread; i++)
	{
	  if(pthread_join(tabThread[i], &res) != 0)
	    perror("Erreur pthread_join");
	  if(res != NULL)
	    free(res);
	}
      close(gThread.gFile.sockPair[0]);
      close(gThread.gFile.sockPair[1]);
      free(tabThread);
      /* Liberation de la gThread */
      testamentGThread(&gThread);
      /* fermeture du socket d'ecoute */
      close(socket);
      printf("\nBye\n");
    }
  else 
    {
      fprintf(stderr, "\nUsage serveur : %s <port> <nombre connexion>\n", argv[0]);
      exit(1);
    }
  return 0;
}
